package net.jumpengine.ui;

import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import net.jumpengine.Manager;
import net.jumpengine.bean.Base;
import net.jumpengine.po.Border;

/**
  * 一个LED样式的数字显示器, 数字的大小由高度决定
 * <br /><br />
 * <b>作者:&nbsp;</b>张天文 <br />
 * <b>日期:&nbsp;</b>2020年3月3日 下午7:57:06<br />
 * @date
 */
public class LEDBox extends Base {
	private int val=0;
	private Border border;
	private Color color=Color.valueOf("#DB4D17");
	private Color backColor=Color.grayRgb(100);
	private int count=3;
	private int r,cx,cy,cwidth,cheight;
	private int oneWidth,left,tmp,tmp1;
	private boolean change=true;
	
	//高度转宽度,水平间隔比例,垂直间隔比例
	private static double heightToWidth=0.563876;
	
	/** 坐标比例, 1x2y3x4y,以此类推, 另外2,5,6由0,1,4镜像而来  */
	private double[][] data=new double[][] {
		{0.109375,0.044052,0.296875,0.154185},
		{0.078125,0.053303,0.273437,0.163436,0.273437,0.410132,0.078125,0.493832},
		{},
		{0.275781,0.419383,0.139843,0.501762,0.275781,0.582819},
		{0.079687,0.505726,0.275   ,0.615859,0.275   ,0.836123,0.079687,0.946255},
		{},
		{}
	};
	
	/** 数字样式 */
	private byte[] style=new byte[] {0b01110111,0b0100100,0b01011101,0b01101101,0b00101110,0b01101011,0b01111011
			,0b00100101,0b01111111,0b01101111};
	
	public LEDBox(int x, int y, int height,int count,Border border) {
		this(x, y, (int)(height*heightToWidth*count), height,1,count,border);
	}
	
	/**
	  * 基础构造方法,层级为0
	 * @param x x坐标
	 * @param y y坐标
	 * @param width 宽度
	 * @param height 高度
	 * @param count 数字个数
	 * @param border 边框
	 */
	public LEDBox(int x, int y, int width, int height,int count,Border border) {
		this(x, y, width, height,1,count,border);
	}
	
	public LEDBox(int x, int y, int width, int height, int index,int count,Border border) {
		super(x, y, width, height, index);
		this.border=border;
		this.count=count;
	}

	@Override
	public void draw(GraphicsContext g) {
		if(change) {
			math();
			change=false;
		}
		g.setFill(border.getColor());
		if(r==0) {
			g.fillRect(x, y, width, height);
		}else {
			g.fillRoundRect(x, y, width, height, r, r);
		}
		g.setFill(backColor);
		if(r==0) {
			g.fillRect(cx,cy,cwidth,cheight);
		}else {
			g.fillRoundRect(cx,cy, cwidth, cheight, r, r);
		}
		
		g.setFill(color);
		tmp1=val;
		for(int i=(count-1);i>=0;i--) {
			tmp=tmp1 % 10;
			tmp1=tmp1 / 10;
			drawNumber(x+left+oneWidth*i,cy,tmp,g);
			if(change)Manager.getLog().debug("i:%d,left:%d,oneWidth*i:%d,left+oneWidth*i:%d", i,left,oneWidth*i,left+oneWidth*i);
			if(tmp1==0)break;
		}
	}
	
	private void drawNumber(int x, int y, int val,GraphicsContext g) {
		int b=style[val];
		for(int i=0;i<7;i++) {
			if((b & 1)==1)mathPath(x,y,i,g);
			b=b >> 1;
		}
	}
	
	private void mathPath(int x,int y,int val,GraphicsContext g) {
		g.beginPath();
		if(val==0) {
			g.moveTo(x+data[0][0]*oneWidth,y+data[0][1]*cheight);
			g.lineTo(x+(1-data[0][0])*oneWidth,y+data[0][1]*cheight);
			g.lineTo(x+(1-data[0][2])*oneWidth,y+data[0][3]*cheight);
			g.lineTo(x+data[0][2]*oneWidth,y+data[0][3]*cheight);
		}else if(val==1) {
			g.moveTo(x+data[1][0]*oneWidth,y+data[1][1]*cheight);
			g.lineTo(x+data[1][2]*oneWidth,y+data[1][3]*cheight);
			g.lineTo(x+data[1][4]*oneWidth,y+data[1][5]*cheight);
			g.lineTo(x+data[1][6]*oneWidth,y+data[1][7]*cheight);
		}else if(val==2) {
			g.moveTo(x+(1-data[1][0])*oneWidth,y+data[1][1]*cheight);
			g.lineTo(x+(1-data[1][2])*oneWidth,y+data[1][3]*cheight);
			g.lineTo(x+(1-data[1][4])*oneWidth,y+data[1][5]*cheight);
			g.lineTo(x+(1-data[1][6])*oneWidth,y+data[1][7]*cheight);
		}else if(val==3) {
			g.moveTo(x+data[3][0]*oneWidth,y+data[3][1]*cheight);
			g.lineTo(x+data[3][2]*oneWidth,y+data[3][3]*cheight);
			g.lineTo(x+data[3][4]*oneWidth,y+data[3][5]*cheight);
			g.lineTo(x+(1-data[3][4])*oneWidth,y+data[3][5]*cheight);
			g.lineTo(x+(1-data[3][2])*oneWidth,y+data[3][3]*cheight);
			g.lineTo(x+(1-data[3][0])*oneWidth,y+data[3][1]*cheight);
		}else if(val==4) {
			g.moveTo(x+data[4][0]*oneWidth,y+data[4][1]*cheight);
			g.lineTo(x+data[4][2]*oneWidth,y+data[4][3]*cheight);
			g.lineTo(x+data[4][4]*oneWidth,y+data[4][5]*cheight);
			g.lineTo(x+data[4][6]*oneWidth,y+data[4][7]*cheight);
		}else if(val==5) {
			g.moveTo(x+(1-data[4][0])*oneWidth,y+data[4][1]*cheight);
			g.lineTo(x+(1-data[4][2])*oneWidth,y+data[4][3]*cheight);
			g.lineTo(x+(1-data[4][4])*oneWidth,y+data[4][5]*cheight);
			g.lineTo(x+(1-data[4][6])*oneWidth,y+data[4][7]*cheight);
		}else if(val==6) {
			g.moveTo(x+data[0][0]*oneWidth,y+(1-data[0][1])*cheight);
			g.lineTo(x+(1-data[0][0])*oneWidth,y+(1-data[0][1])*cheight);
			g.lineTo(x+(1-data[0][2])*oneWidth,y+(1-data[0][3])*cheight);
			g.lineTo(x+data[0][2]*oneWidth,y+(1-data[0][3])*cheight);
		}
		g.closePath();
		g.fill();
	}

	private void math() {
		r=border==null?0:border.getRadius();
		cx=x+(border==null?0:border.getLeft());
		cy=y+(border==null?0:border.getTop());
		cwidth= width-(border==null?0:border.getRight())-(border==null?0:border.getLeft());
		cheight=height-(border==null?0:border.getBottom())-(border==null?0:border.getTop());
		oneWidth=(int) (cheight*heightToWidth);
		
		int rCount=cwidth/oneWidth;
		count=count>rCount?rCount:count;
		left=(cwidth-count*oneWidth)/2+1;
		//Manager.getLog().debug("rCount:%d,count:%d,cwidth:%d,count*oneWidth:%d,left:%d",rCount,count,cwidth,count*oneWidth,left);
	}

	public int getVal() {
		return val;
	}

	public void setVal(int val) {
		if(val>=0)this.val = val;
	}
	
	public void add() {
		val+=1;
	}
	public void add(int add) {
		val+=add;
	}

	public Border getBorder() {
		return border;
	}
	public void setBorder(Border border) {
		this.border = border;
		change=true;
	}
	
	@Override
	public void setWidth(int width) {
		super.setWidth(width);
		change=true;
	}
	
	@Override
	public void setHeight(int height) {
		super.setHeight(height);
		change=true;
	}

	public Color getColor() {
		return color;
	}
	public void setColor(Color color) {
		this.color = color;
	}

	public Color getBackColor() {
		return backColor;
	}
	public void setBackColor(Color backColor) {
		this.backColor = backColor;
	}

	public int getCount() {
		return count;
	}
	public void setCount(int count) {
		this.count = count;
		change=true;
	}

}
